Skip to content

feat(ui): add per-user locale preference for date/time formatting - #768

Merged
adubovikov merged 1 commit into
sipcapture:homer11from
fredrik-dahlgren:feat/ui-locale-preference
Jun 2, 2026
Merged

feat(ui): add per-user locale preference for date/time formatting#768
adubovikov merged 1 commit into
sipcapture:homer11from
fredrik-dahlgren:feat/ui-locale-preference

Conversation

@fredrik-dahlgren

Copy link
Copy Markdown
Contributor

Hardcoded en-GB / en-US locales rendered dates the same way for every viewer, ignoring the browser preference.

Adds a LocaleProvider (mirrors ThemeProvider) backed by localStorage and exposed under Settings → Profile → "Date & time format".

@fredrik-dahlgren
fredrik-dahlgren force-pushed the feat/ui-locale-preference branch from 049b8bc to 45a4260 Compare June 1, 2026 11:05
@adubovikov
adubovikov requested a review from Copilot June 1, 2026 15:11
@adubovikov

Copy link
Copy Markdown
Member

thank you!

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

This PR adds a per-user (per-browser) locale preference to drive Intl.DateTimeFormat across the UI, so date/time rendering can follow the viewer’s chosen locale instead of a hardcoded en-GB/en-US.

Changes:

  • Introduces a LocaleProvider (mirroring the existing ThemeProvider) backed by localStorage, and wires it into App.
  • Adds a locale selector to Settings → Profile → Date & time format with a sample preview.
  • Updates multiple dashboard panels/modals to format timestamps using the resolved locale.

Reviewed changes

Copilot reviewed 16 out of 16 changed files in this pull request and generated 4 comments.

Show a summary per file
File Description
src/ui/src/settings/ProfilePanel.tsx Adds “Date & time format” settings card and locale selection UI.
src/ui/src/lib/datetime.ts Adds helper factory + hook for memoized Intl.DateTimeFormat based on locale context.
src/ui/src/dashboard/widgets/ResultsPanel.tsx Switches timestamp formatting from hardcoded locale to locale context.
src/ui/src/dashboard/widgets/ClockPanel.tsx Uses locale context for clock date/time formatting.
src/ui/src/dashboard/TransactionModal.tsx Uses locale context for datetime rendering in tables/events.
src/ui/src/dashboard/QosPanel.tsx Uses locale context for chart axis time formatting and prop threading.
src/ui/src/dashboard/OTLPTraceModal.tsx Uses locale context for timestamp formatting.
src/ui/src/dashboard/OTLPMetricsSeriesModal.tsx Uses locale context for timestamp formatting.
src/ui/src/dashboard/OTLPLogsTraceModal.tsx Uses locale context for timestamp formatting.
src/ui/src/dashboard/OTLPLogRowModal.tsx Uses locale context for timestamp formatting.
src/ui/src/dashboard/MessageModal.tsx Uses locale context for datetime display in metadata grid.
src/ui/src/dashboard/flow/flow-data.ts Adds optional locale to flow-building options and uses it in formatting.
src/ui/src/dashboard/components/TimeRangePicker.tsx Uses locale context for human-readable time range display.
src/ui/src/dashboard/CallFlow.tsx Passes locale into flow builder and updates memo deps.
src/ui/src/components/locale/locale-provider.tsx New provider/hook implementing persisted locale preference + resolution.
src/ui/src/App.tsx Wraps the app in LocaleProvider so locale is available across UI.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment thread src/ui/src/components/locale/locale-provider.tsx Outdated
Comment thread src/ui/src/components/locale/locale-provider.tsx
Comment thread src/ui/src/components/locale/locale-provider.tsx Outdated
Comment thread src/ui/src/components/locale/locale-provider.tsx
@adubovikov

Copy link
Copy Markdown
Member

@fredrik-dahlgren can you please take a look ?

Hardcoded en-GB / en-US locales rendered dates the same way for every
viewer, ignoring the browser preference. Users whose locale uses ISO 8601
(e.g. sv-SE) had no way to see `2026-06-01` instead of `01/06/2026`.

Adds a LocaleProvider (mirrors ThemeProvider) backed by localStorage and
exposed under Settings → Profile → "Date & time format". The "Auto"
default resolves to `navigator.language`, so users with a Swedish
browser get ISO output without any configuration. The picker lists ~60
BCP-47 tags labelled via Intl.DisplayNames in the active locale. The
"Auto · <tag>" label always shows the real browser default rather than
the currently selected locale, so its meaning stays consistent
regardless of selection.

11 display formatters (MessageModal, TransactionModal, OTLP*,
QosPanel, ClockPanel, ResultsPanel, TimeRangePicker display, flow-data)
now read the locale from context and pass it to Intl.DateTimeFormat
instead of hardcoding `en-GB`. The cosmetic `.replace(',', '')` and the
`hour12: false` / `2-digit` overrides are dropped so the locale's
natural conventions apply; `fractionalSecondDigits: 3` is preserved
where it was (SIP packet timing).

Left untouched: `resolveTimeRange.ts` and `TimeRangePicker`'s input
formatter path. Those use `formatToParts` to read deterministic ISO
components for `<input type="datetime-local">` and timezone math — not
for display — so they keep the existing locale literal.

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Copilot reviewed 16 out of 16 changed files in this pull request and generated 4 comments.

@@ -0,0 +1,112 @@
import { createContext, useCallback, useContext, useEffect, useMemo, useState } from "react"

type LocalePref = "auto" | string
Comment on lines +107 to +112
export const useLocale = () => {
const context = useContext(LocaleProviderContext)
if (context === undefined)
throw new Error("useLocale must be used within a LocaleProvider")
return context
}
Comment on lines +6 to +9
function withTimeZone(opts: DateTimeFormatOptions, timeZone?: string): DateTimeFormatOptions {
if (!timeZone || timeZone === 'local') return opts
return { ...opts, timeZone }
}
Comment on lines +257 to +264
<SelectContent>
<SelectItem value="auto">{`Auto · ${auto}`}</SelectItem>
{localeChoices.map((c) => (
<SelectItem key={c.value} value={c.value}>
{c.label} · {c.value}
</SelectItem>
))}
</SelectContent>
@adubovikov
adubovikov merged commit 59b89bb into sipcapture:homer11 Jun 2, 2026
2 checks passed
@adubovikov

Copy link
Copy Markdown
Member

@fredrik-dahlgren

Copy link
Copy Markdown
Contributor Author

Thanks for finishing this @adubovikov !

@adubovikov

Copy link
Copy Markdown
Member

thank you for great contributions :-)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants